package com.servlet;

import com.method.HandlerMethod;
import com.view.ModelAndView;
import com.web.RequestMappingHandlerMapping;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 龙小虬
 * @date 2021/3/15 10:32
 */
public class DispatcherServlet extends FrameworkServlet{

    RequestMappingHandlerMapping requestMappingHandlerMapping;

    public DispatcherServlet() {
        requestMappingHandlerMapping = new RequestMappingHandlerMapping();
    }


    @Override
    protected void onRefresh() {
        initStrategies();
    }

    protected void initStrategies() {
        initHandlerMappings();
    }

    private void initHandlerMappings() {
        // 初始化容器
        System.out.println(">>>初始化initHandlerMappings对象<<<");
        requestMappingHandlerMapping.registryMapping();
    }

    @Override
    protected void doService(HttpServletRequest req, HttpServletResponse resp) {
        try {
            doDispatch(req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        // 对请求进行解析
        // 1.获取请求的url
        String url = req.getRequestURI();
        // 2.查找请求的url是否存在 获取具体的handler
        HandlerExecutionChain handler = getHandler(url);
        if(handler == null){
            noHandlerFound(req,resp);
            return;
        }
        // 3.执行对应的目标方法
        ModelAndView mv = handler.handler();
        // 4.渲染页面
        render(mv,req,resp);
    }

    protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response){
        try{
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            response.getWriter().print("没有查找到该请求");
        }catch (Exception e){

        }
    }
    private void render(ModelAndView mv, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String view = mv.getView();
        req.getRequestDispatcher("/WEB-INF/view/" + view + ".jsp").forward(req, resp);
    }


    /**
     * 获取具体的handler
     * @param url
     * @return
     */
    public HandlerExecutionChain getHandler(String url) {
        HandlerMethod handler = requestMappingHandlerMapping.getHandler(url);
        if(handler == null){
            return null;
        }
        return new HandlerExecutionChain(handler);
    }
}
